<?php

namespace app\tools;

use Elasticsearch\ClientBuilder;

/**
 * Es搜索引擎
 * Class Elasticsearch
 * @package projects\tools
 */
class Elasticsearch
{

    private static \Elasticsearch\Client $client;

    /**
     * 初始化
     */
    private static function create()
    {
        $host = env('elasticsearch.host') ?: '127.0.0.1';
        $port = env('elasticsearch.port') ?: '9200';
        self::$client = ClientBuilder::create()->setHosts([$host . ':' . $port])->build();
    }


    /**
     * 创建索引
     * @author Du
     * @date 2021/3/16 18:24
     */
    public static function createIndex(string $indexName): bool
    {
        self::create();
        //检测索引是否已存在
        $params_search = [
            'index' => $indexName,
        ];
        $flag_exit = self::$client->indices()->exists($params_search);
        if ($flag_exit === false) {
            //创建索引
            $params = [
                'index' => $indexName,  //索引名称
                'body' => [
                    'settings' => [
                        'number_of_shards' => 5, // 分片 默认5
                        'number_of_replicas' => 1 // 副本、备份 默认1
                    ]
                ]
            ];
            $response = self::$client->indices()->create($params);
            return true;
        }
        return false;
    }

    /**
     * 创建索引类型字段
     * @param string $indexName 索引名称
     * @param string $typeName 类型名称
     * @param array $properties 字段数组
     * @return bool
     */
    public static function createMappings(string $indexName, string $typeName, array $properties = []): bool
    {
        $params = [
            'index' => $indexName,  //索引名称 类似数据库名称
            'type' => $typeName,   //类型名称 类似表名称
            'body' => [
                //字段定义
                'properties' => $properties,
//                [
//                    //字段全部信息
//                    '字段名称' => [
//                        //属性
//                        'type：类型，可以是text、long、short、date、integer、object等',
//                        'index：是否索引，默认为true',
//                        'store：是否存储，默认为false',
//                        'analyzer：分词器，这里的ik_max_word即使用ik分词器'
//                    ],
//                ]
            ]
        ];
        $response = self::$client->indices()->putMapping($params);
        if ($response && $response['acknowledged'] === true) {
            return true;
        }
        return false;
    }

    /**
     * 添加数据
     * @param string $indexName
     * @param string $typeName
     * @param int $id
     * @param array $data
     * @return bool
     */
    public static function addData(string $indexName, string $typeName, int $id, array $data): bool
    {
        $params = [
            'index' => $indexName,
            'type' => $typeName,
            'id' => $id,
            'body' => $data,
        ];
        $response = self::$client->index($params);
        return true;
    }

    /**
     * 更新数据
     * @param string $indexName
     * @param string $typeName
     * @param int $id
     * @param array $data
     * @return bool
     */
    public function updateData(string $indexName, string $typeName,int $id, array $data): bool
    {
        $params = [
            'index' => $indexName,
            'type' => $typeName,
            'id' => $id,
            'body' => [
                'doc' => $data
            ]
        ];
        $response = self::$client->update($params);
        return true;
    }

    /**
     * 删除数据
     * @param string $indexName
     * @param string $typeName
     * @param int $id
     * @return bool
     */
    public function deleteData(string $indexName, string $typeName, int $id): bool
    {
        $params = [
            'index' => $indexName,
            'type' => $typeName,
            'id' => $id,
        ];
        $response = self::$client->delete($params);
        return true;
    }

    /**
     * 查询数据
     * @param array $filter
     * @param string $orderName
     * @param string $orderSort
     * @param int $start
     * @param int $size
     */
    public function searchData(array $filter, string $orderName, string $orderSort, int $start, int $size)
    {
        $params = [
            'index' => $this->indexName,
            'type' => $this->typeName,
            'body' => $filter,
            'sort' => [$orderName => ['order' => $orderSort]],
        ];
        $results = $this->client->search($params);
        dd($results);
    }
}